package com.liming.auth.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liming.auth.mapper.UserAddressMapper;
import com.liming.auth.service.RegionService;
import com.liming.auth.service.UserAddressService;
import com.liming.common.constant.SystemConstants;
import com.liming.common.enums.DefaultAddressEnum;
import com.liming.common.exception.BusinessException;
import com.liming.common.pojo.dto.authinfo.AddOrUpdateUserAddressDTO;
import com.liming.common.pojo.entity.BaseEntity;
import com.liming.common.pojo.entity.authinfo.UserAddress;
import com.liming.common.pojo.vo.authinfo.mini.MiniAddressVO;
import com.liming.common.util.BeanUtils;
import com.liming.common.util.ThreadLocalUtils;
import com.liming.common.util.mybatisplus.MPUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author liming
 * @date 2025/1/20
 */
@Service
@AllArgsConstructor
public class UserAddressServiceImpl extends ServiceImpl<UserAddressMapper, UserAddress>
        implements UserAddressService, MPUtil<UserAddress> {

    private final RegionService regionService;

    @Override
    public List<MiniAddressVO> addressList() {
        Map<Long, String> regionIdAndNameMap = regionService.idAndNameMap();
        return lambdaQuery()
                .eq(UserAddress::getUserId, ThreadLocalUtils.get(SystemConstants.ID))
                .orderByDesc(UserAddress::getIsDefault)
                .list()
                .stream()
                .map(entity -> {
                    MiniAddressVO vo = BeanUtils.toBean(entity, MiniAddressVO.class);
                    // 就差 regionName
                    String pName = regionIdAndNameMap.getOrDefault(entity.getProvinceId(), "");
                    String cName = regionIdAndNameMap.getOrDefault(entity.getCityId(), "");
                    String dName = regionIdAndNameMap.getOrDefault(entity.getDistrictId(), "");
                    String sName = regionIdAndNameMap.getOrDefault(entity.getStreetId(), "");
                    vo.setProvinceName(pName);
                    vo.setCityName(cName);
                    vo.setDistrictName(dName);
                    vo.setStreetName(sName);
                    vo.setRegionName(pName + cName + dName + sName);
                    return vo;
                })
                .toList();
    }

    @Override
    @Transactional
    public Boolean addOrUpdateAddress(AddOrUpdateUserAddressDTO dto) {
        Long id = dto.getId();
        UserAddress userAddress = new UserAddress();
        org.springframework.beans.BeanUtils.copyProperties(dto, userAddress);
        long userId = Long.parseLong(ThreadLocalUtils.get(SystemConstants.ID));
        userAddress.setUserId(userId);
        // 判断传来的isDefault 是否为 1
        if (ObjectUtil.equal(dto.getIsDefault(), DefaultAddressEnum.DEFAULT_ADDRESS.getCode())) {
            // 删除之前的默认地址
            lambdaUpdate()
                    .eq(UserAddress::getUserId, userId)
                    .eq(UserAddress::getIsDefault, DefaultAddressEnum.DEFAULT_ADDRESS.getCode())
                    .set(UserAddress::getIsDefault, DefaultAddressEnum.NOT_DEFAULT_ADDRESS.getCode())
                    .update();
        }
        if (ObjectUtil.isNull(id)) {
            // 新增
            Assert.isTrue(save(userAddress), () -> new BusinessException("新增用户地址失败"));
            return true;
        }
        // 更新
        Assert.isTrue(updateById(userAddress), () -> new BusinessException("更新用户地址失败"));
        return true;
    }

    @Override
    public Map<Long, String> addressInfoByIds(List<Long> userAddressIds) {
        Map<Long, String> regionIdAndNameMap = regionService.idAndNameMap();
        return lambdaQuery().in(BaseEntity::getId, userAddressIds).list()
                .stream()
                .collect(Collectors.toMap(BaseEntity::getId, k -> {
                    String sb = k.getContactName() + "/" +
                            k.getContactPhone() + "/" +
                            regionIdAndNameMap.getOrDefault(k.getProvinceId(), "") +
                            regionIdAndNameMap.getOrDefault(k.getCityId(), "") +
                            regionIdAndNameMap.getOrDefault(k.getDistrictId(), "") +
                            regionIdAndNameMap.getOrDefault(k.getStreetId(), "") +
                            k.getAddress();
                    return sb;
                }));
    }
}
